package com.fa.ojcodesandbox.utils;

import cn.hutool.core.util.StrUtil;
import com.fa.ojcodesandbox.model.ExecuteMessage;
import org.springframework.util.StopWatch;

import java.io.*;

/**
 * ClassName: ProcessUtils
 * Package: com.fa.ojcodesandbox.utils
 * Description: 进程工具类
 *
 * @Author:
 * @Create: 2024/4/27 - 14:24
 * @Version: v1.0
 */
public class ProcessUtils {

    /**
     * 获取进程信息
     * @param process 进程
     * @param operationName 操作的名称
     * @return
     */
    public static ExecuteMessage getRunProcessResult(Process process, String operationName) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            // 等待程序执行，获取错误码
            int exitValue = process.waitFor();
            if (exitValue == 0) {
                //等于0，说明是正常退出
                System.out.println(operationName + "成功");
                // 分批获取进程的正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                StringBuilder outputStringBuilder = new StringBuilder();
                //逐行读取
                String outputLine;
                while ((outputLine = bufferedReader.readLine()) != null) {
                    outputStringBuilder.append(outputLine);
                }
                executeMessage.setExitValue(exitValue);
                executeMessage.setMessage(outputStringBuilder.toString());
            } else {
                // 异常退出
                System.out.println(operationName + "失败，错误码为：" + exitValue);

                // 分批获取进程的正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                //逐行读取
                String outputLine;
                StringBuilder outputStringBuilder = new StringBuilder();
                while ((outputLine = bufferedReader.readLine()) != null) {
                    outputStringBuilder.append(outputLine);
                }
                // 分批获取进程的error输出
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                StringBuilder errorOutputStringBuilder = new StringBuilder();
                // 逐行读取
                String errorOutputLine;
                while ((errorOutputLine = errorBufferedReader.readLine()) != null) {
                    errorOutputStringBuilder.append(errorOutputLine);
                }
                executeMessage.setExitValue(exitValue);
                executeMessage.setMessage(outputStringBuilder.toString());
                executeMessage.setErrorMessage(errorOutputStringBuilder.toString());
            }
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        } catch (InterruptedException | IOException e) {
            throw new RuntimeException(e);
        }
        return executeMessage;
    }


    /**
     * 获取交换式进程信息
     * @param process 进程
     * @param operationName 操作的名称
     * @return
     */
    public static ExecuteMessage getCommutativeRunProcessResult(Process process, String operationName, String args) {
        // todo 该方法未完整实现
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            InputStream inputStream = process.getInputStream();

            // 向控制台输入程序
            OutputStream outputStream = process.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            String[] s = args.split(" ");
            String join = StrUtil.join("\n" ,s) + "\n";
            outputStreamWriter.write(join);
            // flush相当于按了回车，执行输入的发送
            outputStreamWriter.flush();

            // 分批获取进程的正常输出
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder outputStringBuilder = new StringBuilder();
            //逐行读取
            String outputLine;
            while ((outputLine = bufferedReader.readLine()) != null) {
                outputStringBuilder.append(outputLine);
            }
            executeMessage.setMessage(outputStringBuilder.toString());
            // 这里需要进行资源的释放，否则会卡死
            outputStreamWriter.close();
            outputStream.close();
            inputStream.close();
            process.destroy();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return executeMessage;
    }
}
